package pkg.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.sourceforge.stripes.action.After;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.validation.ValidationErrors;
import pkg.dao.EntityDAO;
import pkg.entity.Teacher;
import pkg.entity.Auction;
import pkg.entity.Bid;
import pkg.entity.Grade;
import pkg.filter.TeacherFilter;
import pkg.filter.AuctionFilter;

public class BidActionBean extends BaseActionBean {

    private Auction auction;
    private List<Auction> auctions;
    private Teacher teacher;
    private Map<Grade, List<Teacher>> gradeMap;
    private List<Teacher> teachers;
    private boolean auctionLoaded = false;
    private Bid bid;

    public BidActionBean() {
    }

    @DefaultHandler
    public Resolution bid() {
        
        setTeacher(getDefaultTeacher());
        RedirectResolution result = new RedirectResolution(this.getClass());
        result.addParameter("teacher.id", getTeacher().getId());
        result.addParameter("viewTeacher");
        return result;
    }

    public Resolution viewTeacher() {
        loadGradeMap();
        EntityDAO dao = new EntityDAO();
        setTeacher(dao.find(Teacher.class, getTeacher().getId()));

        AuctionFilter f = new AuctionFilter();
        f.setTeacher(getTeacher());

        setAuctions((List<Auction>) dao.findAllByFilter(f));

        if (getAuctions().size() == 1) {
            setAuction(getAuctions().get(0));
            auctionLoaded = true;
            return viewAuction();
        } else {
            return new ForwardResolution("/ShowTeacherAuctions.jsp");
        }
    }

    public Resolution viewAuction() {
        loadGradeMap();
        if (!auctionLoaded) {
            // viewTeacher sets auctionLoaded if there is only one auction for the teacher
            AuctionFilter f = new AuctionFilter();
            f.setAuction(getAuction());
            EntityDAO dao = new EntityDAO();
            setAuction((Auction) dao.findOneByFilter(f));
            setTeacher(getAuction().getTeacher());
        }
        return new ForwardResolution("/ShowAuction.jsp");
    }

    @After(stages = LifecycleStage.BindingAndValidation)
    public void loadRequestIfErrors() {
        ValidationErrors ve = getContext().getValidationErrors();
        if (ve.size() > 0 && getAuction() != null && getAuction().getId() != null) {
            EntityDAO sb = new EntityDAO();
            setAuction(sb.find(Auction.class, getAuction().getId()));
        }
        loadLookups();
    }

    public void loadLookups() {
        setTeachers(new ArrayList<Teacher>());
        EntityDAO dao = new EntityDAO();
        TeacherFilter f = new TeacherFilter();
        getTeachers().addAll(dao.findAllByFilter(f));
    }

    private void loadGradeMap() {
        if (gradeMap != null) {
            return;
        }
        EntityDAO dao = new EntityDAO();
        TeacherFilter f = new TeacherFilter();

        f.setSortColumn("gradeKey");

        List<Teacher> teachers = dao.findAllByFilter(f);
        gradeMap = new LinkedHashMap<Grade, List<Teacher>>();

        Grade lastGrade = null;
        List<Teacher> gradeList = new ArrayList<Teacher>();

        Comparator<Teacher> c = new Comparator<Teacher>() {

            public int compare(Teacher t, Teacher t1) {
                return t.getLastName().compareTo(t1.getLastName());
            }
        };

        for (Teacher t : teachers) {
            if (!t.getGrade().equals(lastGrade)) {
                if (lastGrade != null) {
                    Collections.sort(gradeList, c);
                    gradeMap.put(lastGrade, gradeList);
                    lastGrade = t.getGrade();
                    gradeList = new ArrayList<Teacher>();
                }
                lastGrade = t.getGrade();
            }
            gradeList.add(t);
        }
        Collections.sort(gradeList, c);
        gradeMap.put(lastGrade, gradeList);
    }

    //<editor-fold defaultstate="collapsed" desc=" Setters/Getters ">
    public Auction getAuction() {
        return auction;
    }

    public void setAuction(Auction category) {
        this.auction = category;
    }

    private Teacher getDefaultTeacher() {
        EntityDAO dao = new EntityDAO();
        TeacherFilter f = new TeacherFilter();
        f.setPrimary(true);
        setTeacher((Teacher) dao.findOneByFilter(f));
        return getTeacher();
    }

    public List<Auction> getAuctions() {
        return auctions;
    }

    public void setAuctions(List<Auction> auctions) {
        this.auctions = auctions;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    public Map<Grade, List<Teacher>> getGradeMap() {
        return gradeMap;
    }

    public void setGradeMap(Map<Grade, List<Teacher>> gradeMap) {
        this.gradeMap = gradeMap;
    }

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<Teacher> teachers) {
        this.teachers = teachers;
    }

    public Bid getBid() {
        return bid;
    }

    public void setBid(Bid bid) {
        this.bid = bid;
    }
    //</editor-fold>
}
